package com.ogms.dge.container.modules.data.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.networknt.schema.ValidationMessage;
import com.ogms.dge.container.common.utils.FileUtils;
import com.ogms.dge.container.common.utils.PageUtils;
import com.ogms.dge.container.common.utils.R;
import com.ogms.dge.container.modules.common.entity.UploadRecordEntity;
import com.ogms.dge.container.modules.common.enums.UploadRecordStatusEnum;
import com.ogms.dge.container.modules.common.service.impl.UploadRecordServiceImpl;
import com.ogms.dge.container.modules.data.converter.SourceConverter;
import com.ogms.dge.container.modules.data.dto.FileNodeDto;
import com.ogms.dge.container.modules.data.entity.RecordEntity;
import com.ogms.dge.container.modules.data.entity.SourceEntity;
import com.ogms.dge.container.modules.data.service.SourceService;
import com.ogms.dge.container.modules.fs.entity.dto.UploadResultDto;
import com.ogms.dge.container.modules.method.controller.AbstractController;
import com.ogms.dge.container.modules.sys.service.impl.SysUserServiceImpl;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;


/**
 * 数据源
 *
 * @author Lingkai Shi
 * @email lingkai.shi@nnu.edu.cn
 * @date 2024-09-23 15:10:30
 */
@RestController
@RequestMapping("data/source")
public class SourceController extends AbstractController {
    @Autowired
    private SourceService sourceService;

    @Resource
    private SourceConverter sourceConverter;

    @Autowired
    private SysUserServiceImpl sysUserService;

    @Autowired
    private UploadRecordServiceImpl uploadRecordService;

    @Value("${container.data.dsd}")
    private String data_dsd;

    /**
     * 列表
     */
    @RequestMapping("/list")
//    @RequiresPermissions("data:source:list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = sourceService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/uuid/{uuid}")
    public R infoByUuid(@PathVariable("uuid") String uuid) {
        SourceEntity source = sourceService.getOne(new QueryWrapper<SourceEntity>().eq("uuid", uuid));

        return R.ok().put("source", sourceConverter.po2Vo(source, sysUserService));
    }

    @RequestMapping("/info/name/{name}")
    public R infoByName(@PathVariable("name") String name) {
        SourceEntity source = sourceService.getOne(new QueryWrapper<SourceEntity>().eq("name", name));

        return R.ok().put("source", sourceConverter.po2Vo(source, sysUserService));
    }

    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
//    @RequiresPermissions("data:record:info")
    public R info(@PathVariable("id") Long id) {
        SourceEntity source = sourceService.getById(id);

        return R.ok().put("source", sourceConverter.po2Vo(source, sysUserService));
    }

    /**
     * 扫描，并返回文件夹结构
     */
    @RequestMapping("/scan/{uuid}")
    public R scan(@PathVariable("uuid") String uuid) {
        SourceEntity source = sourceService.getOne(new QueryWrapper<SourceEntity>().eq("uuid", uuid));
        String baseUrl = "";
        if (source.getIsLocalPath()) {
            baseUrl = source.getLocalPath();
        } else {
            baseUrl = new File(data_dsd, source.getUuid()).getAbsolutePath();
        }
        File root = new File(baseUrl);
        if (!root.exists()|| !root.isDirectory()) {
            return R.error("File Not Found");
        }

        FileNodeDto fileTree = FileUtils.buildFileTree(root, root.getPath());
        return R.ok().put("data", fileTree);
    }

    @RequestMapping("/save")
    public R save(@RequestParam String type, @RequestParam(required = false) Long recordId, @RequestParam(required = false) String localPath, @RequestBody SourceEntity source) {
        if ("upload".equals(type)) {
            // 处理上传
            UploadRecordEntity record = uploadRecordService.getById(recordId);
            source.setCreateUserId(getUserId());
            source.setCreateTime(new Date());
            source.setUuid(record.getPackageUuid());
            source.setIsLocalPath(false);
            sourceService.save(source);

            record.setStatus(UploadRecordStatusEnum.SECOND_CONFIG.getCode());
            uploadRecordService.saveOrUpdate(record);
            return R.ok().put("uuid", record.getPackageUuid());
        } else if ("local".equals(type)) {
            // 处理本地路径保存
            String uuid = UUID.randomUUID().toString();
            source.setCreateUserId(getUserId());
            source.setCreateTime(new Date());
            source.setUuid(uuid);
            source.setIsLocalPath(true);
            source.setLocalPath(localPath);
            sourceService.save(source);

            return R.ok().put("uuid", uuid);
        }
        return R.error("无效的请求类型");
    }

    @ApiOperation("用户上传数据源实体")
    @PostMapping("/upload")
    public R uploadSource(/*HttpSession session,*/
            MultipartFile file,
            String fileName,
            Integer chunkIndex,
            Integer chunks) {

        Map<String, Object> result = sourceService.uploadSource(getUserId(), file, fileName, chunkIndex, chunks);
        return R.ok().put(result);
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
//    @RequiresPermissions("data:source:update")
    public R update(@RequestBody SourceEntity source) {
        sourceService.updateById(source);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
//    @RequiresPermissions("data:source:delete")
    public R delete(@RequestBody Long[] ids) {
        sourceService.delete(ids);
        return R.ok();
    }

    @RequestMapping("/validate")
    public R validate(@RequestBody Map<String, Object> json) throws JsonProcessingException {
        List<ValidationMessage> list = sourceService.validate(json);
        if (list.isEmpty()) {
            return R.ok();
        } else {
            return R.error(list.toString());
        }
    }

    @RequestMapping("/insValidate")
    public R insValidate(@RequestBody Map<String, Object> json) throws JsonProcessingException {
        List<ValidationMessage> list = sourceService.insValidate(json);
        if (list.isEmpty()) {
            return R.ok();
        } else {
            return R.error(list.toString());
        }
    }

}
